home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / datatypes / aiff / source / stackcall.asm < prev   
Assembly Source File  |  1978-06-29  |  6KB  |  182 lines

  1. **
  2. **      StackCall.asm
  3. **
  4. **      Stack swap & stack size check routines
  5. **
  6. **      Copyright © 1990-1994 by Olaf `Olsen' Barthel
  7. **              All Rights Reserved
  8. **
  9. **      :ts=8
  10. **
  11.  
  12.         include "exec/types.i"
  13.         include "exec/tasks.i"
  14.         include "exec/memory.i"
  15.         include "exec/execbase.i"
  16.  
  17.         include "dos/dos.i"
  18.         include "dos/dosextens.i"
  19.  
  20. *----------------------------------------------------------------------
  21.  
  22. CALL    macro
  23.         xref    _LVO\1
  24.         jsr     _LVO\1(a6)
  25.         endm
  26.  
  27. *----------------------------------------------------------------------
  28.  
  29. ARG_SUCCESS     equ     4+5*4
  30. ARG_STACKSIZE   equ     ARG_SUCCESS+4
  31. ARG_ARGCOUNT    equ     ARG_STACKSIZE+4
  32. ARG_ROUTINE     equ     ARG_ARGCOUNT+4
  33. ARG_ARGS        equ     ARG_ROUTINE+4
  34.  
  35. TRUE            equ     1
  36. FALSE           equ     0
  37.  
  38. SysBase        equ    4
  39.  
  40. *----------------------------------------------------------------------
  41.  
  42.         csect   text,0,0,1,2
  43.  
  44. *----------------------------------------------------------------------
  45.  
  46.         xdef    _StackCall
  47.  
  48.         ;       LONG __stdargs StackCall(       LONG *Success,
  49.         ;                                       LONG StackSize,
  50.         ;                                       LONG ArgCount,
  51.         ;                                       LONG (* __stdargs Function)(...),
  52.         ;                                       ...);
  53.         ;
  54.         ;       Calls a function with parameters on a newly-allocated
  55.         ;       stack. Caution: assumes all arguments are 32 bits wide.
  56.  
  57. _StackCall:
  58.  
  59.         movem.l d2/d3/a2/a3/a6,-(sp)            ; Save registers
  60.  
  61.         move.l  ARG_STACKSIZE(sp),d0            ; Get desired stack size
  62.         add.l   #15+StackSwapStruct_SIZEOF,d0   ; Round to next...
  63.         and.l   #-16,d0                         ; ...quad long word
  64.         move.l  d0,d2                           ; Save it for later
  65.         move.l  #MEMF_PUBLIC,d1                 ; Well?
  66.         move.l  SysBase,a6                 ; Get SysBase
  67.  
  68.         CALL    AllocMem                        ; Allocate the memory
  69.         tst.l   d0                              ; Success?
  70.         beq.b   1$                              ; Exit if not
  71.  
  72.         move.l  d0,a2                           ; Remember base adress
  73.  
  74.         add.l   #StackSwapStruct_SIZEOF,d0      ; Skip the header
  75.         move.l  d0,stk_Lower(a2)                ; Store the stack lower bound
  76.  
  77.         move.l  a2,a3                           ; Get the base address
  78.         add.l   d2,a3                           ; Add the allocation size
  79.         move.l  a3,stk_Upper(a2)                ; Store the stack upper bound
  80.  
  81.         move.l  ARG_ARGCOUNT(sp),d0             ; Get the number of arguments
  82.         beq.b   3$                              ; Skip if none
  83.  
  84.         moveq   #4,d1                           ; One long word per argument
  85.         mulu    d0,d1                           ; Nasty
  86.         ext.l   d1                              ; Forget the upper word
  87.         addq.l  #4,d1                           ; One for predecrement
  88.         sub.l   d1,a3                           ; Pull it down
  89.  
  90.         subq.l  #1,d0                           ; Subtract one for DBRA
  91.         lea.l   ARG_ARGS(sp),a0                 ; Get the source argument list
  92.         move.l  a3,a1                           ; Get the destination argument list
  93.  
  94. 2$      move.l  (a0)+,(a1)+                     ; Copy the parameters
  95.         dbra    d0,2$                           ; Loop until all is copied
  96.  
  97. 3$      move.l  a3,stk_Pointer(a2)              ; Store the new stack pointer
  98.  
  99.         move.l  ARG_ROUTINE(sp),a3              ; Get address of the routine to call
  100.  
  101.         move.l  a2,a0                           ; Swap the stack
  102.         CALL    StackSwap
  103.  
  104.         jsr     (a3)                            ; Call the routine
  105.         move.l  d0,d3                           ; Save the result
  106.  
  107.         move.l  a2,a0                           ; Swap the stack
  108.         CALL    StackSwap
  109.  
  110.         move.l  a2,a1                           ; Get the base address
  111.         move.l  d2,d0                           ; Get the allocation length
  112.         CALL    FreeMem                         ; Free the memory
  113.  
  114.         move.l  ARG_SUCCESS(sp),a0              ; Flag as success
  115.         move.l  #TRUE,(a0)
  116.  
  117.         move.l  d3,d0                           ; Return the result
  118.  
  119.         movem.l (sp)+,d2/d3/a2/a3/a6            ; Restore registers
  120.         rts
  121.  
  122. 1$      move.l  ARG_SUCCESS(sp),a0              ; Flag as failure
  123.         move.l  #FALSE,(a0)
  124.  
  125.         movem.l (sp)+,d2/d3/a2/a3/a6            ; Restore registers
  126.         rts
  127.  
  128. *----------------------------------------------------------------------
  129.  
  130.         xdef    @StackSize
  131.         xdef    _StackSize
  132.  
  133.         ;       LONG StackSize(struct Task *Task);
  134.         ;
  135.         ;       Determines the amount of stack still available to a task.
  136.         ;       Pass in NULL as the task address to return the amount
  137.         ;       of stack available to the calling task.
  138.  
  139. _StackSize:
  140.         move.l  4(sp),a0                        ; Get task address
  141.  
  142. @StackSize:
  143.         move.l  a6,-(sp)                        ; Save registers
  144.  
  145.         move.l  SysBase,a6                 ; Get SysBase
  146.  
  147.         move.l  a0,d0                           ; Valid task address?
  148.         beq.b   4$
  149.  
  150.         move.l  TC_SPREG(a0),d0                 ; Remember stack pointer
  151.         bra.b   3$
  152.  
  153. 4$      move.l  a0,a1
  154.         CALL    FindTask                        ; Who am I?
  155.         move.l  d0,a0                           ; That's me
  156.         move.l  sp,d0                           ; Remember stack pointer
  157.  
  158. 3$      cmp.b   #NT_PROCESS,LN_TYPE(a0)         ; Is this a process?
  159.         bne.b   1$
  160.  
  161.         tst.l   pr_CLI(a0)                      ; Is it running as a CLI process?
  162.         beq.b   1$
  163.  
  164.         move.l  pr_ReturnAddr(a0),d1            ; Get upper bound
  165.         addq.l  #4,d1
  166.         move.l  pr_ReturnAddr(a0),a0
  167.         sub.l   (a0),d1                         ; Subtract total stack size
  168.  
  169.         bra.b   2$
  170.  
  171. 1$      move.l  TC_SPLOWER(a0),d1               ; Get lower bound
  172.  
  173. 2$      sub.l   d1,d0                           ; Subtract from stack pointer
  174.  
  175.         move.l  (sp)+,a6                        ; Restore registers
  176.  
  177.         rts
  178.  
  179. *----------------------------------------------------------------------
  180.  
  181.         end
  182.